package com.ruoyi.violate.service.impl;

import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.violate.domain.ViolateTypeShop;
import com.ruoyi.violate.service.IViolateClassNumberService;
import com.ruoyi.web.controller.common.PageReadListener;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import com.ruoyi.violate.mapper.ViolateTilteMapper;
import com.ruoyi.violate.domain.ViolateTilte;
import com.ruoyi.violate.service.IViolateTilteService;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

/**
 * 标题Service业务层处理
 * 
 * @author 谭拓宇
 * @date 2022-12-13
 */
@Service
@Slf4j
public class ViolateTilteServiceImpl implements IViolateTilteService 
{
    @Autowired
    private ViolateTilteMapper violateTilteMapper;

    @Autowired
    private ViolateTypeShopServiceImpl violateTypeShopService ;

    @Autowired
    private IViolateClassNumberService violateClassNumberService;



    /**
     * 查询标题
     * 
     * @param id 标题主键
     * @return 标题
     */
    @Override
    public ViolateTilte selectViolateTilteById(Long id)
    {
        return violateTilteMapper.selectViolateTilteById(id);
    }

    /**
     * 查询标题列表
     * 
     * @param violateTilte 标题
     * @return 标题
     */
    @Override
    public List<ViolateTilte> selectViolateTilteList(ViolateTilte violateTilte)
    {
        //查询数据库所有数据（数据量：50万以上）
        List<ViolateTilte> violateTiltes = violateTilteMapper.selectViolateTilteList(violateTilte);
        return violateTiltes ;
    }



    @Override
    public Long selectViolateTilteListByCount(ViolateTilte violateTilte){
        return violateTilteMapper.selectViolateTilteListByCount(violateTilte);
    }
    /**
     * 新增标题
     * 
     * @param violateTilte 标题
     * @return 结果
     */
    @Override
    public int insertViolateTilte(ViolateTilte violateTilte)
    {
        return violateTilteMapper.insertViolateTilte(violateTilte);
    }

    /**
     * 修改标题
     * 
     * @param violateTilte 标题
     * @return 结果
     */
    @Override
    public int updateViolateTilte(ViolateTilte violateTilte)
    {
        return violateTilteMapper.updateViolateTilte(violateTilte);
    }

    /**
     * 批量删除标题
     * 
     * @param ids 需要删除的标题主键
     * @return 结果
     */
    @Override
    public int deleteViolateTilteByIds(Long[] ids)
    {
        return violateTilteMapper.deleteViolateTilteByIds(ids);
    }

    /**
     * 获取多级类目的集合
     * @param ids
     * @return
     */
    @Override
    public List<ViolateTilte> selectViolateTypeList(String[] ids) {
        return violateTilteMapper.selectViolateTypeList(ids);
    }

    /**
     * 获取yi级类目的集合
     * @param ids
     * @return
     */
    @Override
    public List<ViolateTilte> selectViolateType1List(String[] ids) {
        return violateTilteMapper.selectViolateType1List(ids);
    }

    /**
     * 删除标题信息
     * 
     * @param id 标题主键
     * @return 结果
     */
    @Override
    public int deleteViolateTilteById(Long id)
    {
        return violateTilteMapper.deleteViolateTilteById(id);
    }
    /**
     * 一键全删
     * @return 结果
     */
    @Override
    public int deleteViolateTitleAll(){
        return violateTilteMapper.deleteViolateTitleAll();
    }

    /**
     * 一键去重
     * @return
     */
    @Override
    public int distinctViolateTilte() {
//        //当链接和标题与数据库在数据库中出现重复的，就删除
//        //获取所有的title数据
//        List<ViolateTilte> violateTitles = violateTilteMapper.selectViolateTitles();
//        log.info("获取所有的title数据,数据量：{}",violateTitles.size());
//        //利用set去重
//        Set<ViolateTilte> sets = new TreeSet<>(Comparator.comparing(o -> (o.getUrl() + "" + o.getTilte())));
//        sets.addAll(violateTitles);
//        int count = violateTitles.size() - sets.size() ;
//        //删除全表
//        violateTilteMapper.deleteAll() ;
//        log.info("删除完成！！！");
//        //添加新表
//        for (ViolateTilte vio : sets) {
//            violateTilteMapper.insertViolateTilte(vio) ;
//            log.info("添加新数据！！！");
//        }
//        log.info("去重成功！！！");
//        return count;

        return  violateTilteMapper.distinctViolateTilte() ;
    }

    /**
     * 导入数据tilte表
     * @param filePath
     * @return
     */
    @Override
    public int importFile(String filePath) throws IOException {

        ExecutorService executor = ThreadUtil.newExecutor(5);

        executor.execute(() ->{
            String path = RuoYiConfig.getProfile() + filePath.substring(8, filePath.length());
            System.out.println(path);

//            File file = new File(path);
//            MultipartFile files = getMultipartFile(file);
//            ExcelReader reader = null;
//            try {
//                reader = ExcelUtil.getReader(files.getInputStream());
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        reader.addHeaderAlias("标题", "tilte");
//        reader.addHeaderAlias("链接", "url");
//        reader.addHeaderAlias("价格", "money");
//        reader.addHeaderAlias("类目", "type");
//        reader.addHeaderAlias("利润标签", "states");
//        //获取所有的Excel表格中的tilte
//        List<ViolateTilte> list = reader.readAll(ViolateTilte.class);

            List<ViolateTilte> list = new ArrayList<ViolateTilte>();
            EasyExcel.read(path, ViolateTilte.class, new PageReadListener<ViolateTilte>(dataList -> {
                for (ViolateTilte violateTilte : dataList) {
                    log.info("读取到一条数据{}", JSON.toJSONString(violateTilte));
                    list.add(violateTilte) ;
                }
            })).sheet().doRead();

        String id = IdUtils.simpleUUID() ;
        //关闭线程
            for(ViolateTilte entity :list){
               if (entity.getTilte()== null){
                   continue;
               }
               if (entity.getMoney() == ""){
                   entity.setMoney("0.0");
               }
                    entity.setFileId(id);
                    //把类目拆开成类目1，类目二等
                String[] split = entity.getType().split("》");
                switch (split.length){
                    case 1 :
                        entity.setType1(split[0]);
                        break;
                    case 2 :
                        entity.setType1(split[0]);
                        entity.setType2(split[1]);
                        break;
                    case 3 :
                        entity.setType1(split[0]);
                        entity.setType2(split[1]);
                        entity.setType3(split[2]);
                        break;
                    case 4 :
                        entity.setType2(split[2]);
                        entity.setType3(split[3]);
                        entity.setType4(split[1]);
                        entity.setType1(split[0]);
                        break;
                    case 5 :
                        entity.setType5(split[0]);
                        entity.setType1(split[1]);
                        entity.setType2(split[2]);
                        entity.setType3(split[3]);
                        entity.setType4(split[4]);
                        break;
                }
                //在数据库中violate_tilte表中添加tilte数据
                    this.insertViolateTilte(entity);
            }
            System.out.println("结束线程");
            executor.shutdown();
        });
        return 1 ;
    }



    /**
     * 导入删除模板文件
     * @param filePath
     * @return
     */
    @Override
    public int importFileDelete(String filePath) throws IOException {

        ExecutorService executor = ThreadUtil.newExecutor(5);

        executor.execute(() -> {

            //通过filePath路径，解析excel转化为list
            String path = RuoYiConfig.getProfile() + filePath.substring(8, filePath.length());
            System.out.println(path);
            File file = new File(path);
            MultipartFile files = getMultipartFile(file);
            ExcelReader reader = null;
            try {
                reader = ExcelUtil.getReader(files.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
            reader.addHeaderAlias("标题", "tilte");
            reader.addHeaderAlias("链接", "url");
            reader.addHeaderAlias("价格", "money");
            reader.addHeaderAlias("类目", "type");
            reader.addHeaderAlias("利润标签", "states");
            //获取所有的Excel表格中的tilte
            List<ViolateTilte> list = reader.readAll(ViolateTilte.class);


//            List<ViolateTilte> list = new ArrayList<ViolateTilte>();
//            EasyExcel.read(path, ViolateTilte.class, new PageReadListener<ViolateTilte>(dataList -> {
//                for (ViolateTilte violateTilte : dataList) {
//                    log.info("读取到一条数据{}", JSON.toJSONString(violateTilte));
//                    list.add(violateTilte) ;
//                }
//            })).sheet().doRead();

//            List<ViolateTilte> violateTiltes = violateTilteMapper.selectViolateTiltes();
//            log.info("title数据查询结束");
//            ViolateTilte violateTilte = new ViolateTilte();
//            List<ViolateTilte> violateTitles = this.selectViolateTilteList(violateTilte);

//            Map<String,ViolateTilte> map = new IdentityHashMap<String, ViolateTilte>();
//            for(ViolateTilte vio : violateTitles){
//                String key = "";
//                //我们这里就用student主键字段作为key值
//                String url = vio.getUrl();
//                if(null !=url &&  !"".equals(url)){
//                    key+=url;
//                }
//                map.put(key,vio);
//            }
//            Map<String,ViolateTilte> map2 = new HashMap<String,ViolateTilte>();
//            for(ViolateTilte vio : list){
//                String key = "";
//                //我们这里就用student主键字段作为key值
//                String url = vio.getUrl();
//                if(null !=url &&  !"".equals(url)){
//                    key+=url;
//                }
//                map2.put(key,vio);
//            }
//
//            List<ViolateTilte> violist = new ArrayList<ViolateTilte>();
//            Map<String,List<ViolateTilte>> map3= new HashMap<String,List<ViolateTilte>>();
//            //遍历Map
//            for(Map.Entry<String,ViolateTilte> entry : map.entrySet()){
//                String key = entry.getKey();
//                //判断另一个map是否包含这个key
//                //如果有则是相同数据，如果没有，那就是不同的数据
//                if(!map2.containsKey(key)){
//                    violist.add(map.get(key)) ;
//                }
//            }
//            System.out.println(violist.size());
//            log.info("list集合删除完成后：violist.size=={}",violist.size());
//
//            //删除全表
//            violateTilteMapper.deleteAll() ;
//            log.info("数据库title删除完成！！！");
//            //添加新表
//            for (ViolateTilte vio : violateTitles) {
//                violateTilteMapper.insertViolateTilte(vio) ;
//                log.info("添加新数据！！！");
//            }


            //list中的数据比对删除
            for (ViolateTilte violateTitle : list) {
                if ((violateTitle.getTilte() == null && violateTitle.getUrl() == null) || "".equals (violateTitle.getTilte()) && "".equals(violateTitle.getUrl())){
                    continue;
                }
                violateTilteMapper.importFileDelete(violateTitle) ;
                log.info("删除{}数据",violateTitle);
            }
            System.out.println("结束线程");
            executor.shutdown();
        });
        return 1 ;
    }

    public MultipartFile getMultipartFile(File file) {
        DiskFileItem item = new DiskFileItem("file"
                , MediaType.MULTIPART_FORM_DATA_VALUE
                , true
                , file.getName()
                , (int) file.length()
                , file.getParentFile());
        try {
            OutputStream os = item.getOutputStream();
            os.write(FileUtils.readFileToByteArray(file));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new CommonsMultipartFile(item);
    }

    /**
     * 导出数据
     * @param response
     * @param violateTilte
     */
    public void export(HttpServletResponse response, ViolateTilte violateTilte) throws Exception {
        List<ViolateTilte> list = this.exportViolateTilteList(violateTilte);


//        ExcelUtil<ViolateTilte> util = new ExcelUtil<ViolateTilte>(ViolateTilte.class);
//        util.exportExcel(response, list, "标题数据");

//        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
//        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        //过滤后的数据，保存为excel表格
        Set<String> includeColumnFiledNames = new HashSet<String>();
        includeColumnFiledNames.add("url");
        includeColumnFiledNames.add("tilte");
        includeColumnFiledNames.add("money");
        includeColumnFiledNames.add("type");
        includeColumnFiledNames.add("type1");
        includeColumnFiledNames.add("states");
//        EasyExcel.write(response.getOutputStream(), ViolateTilte.class).includeColumnFiledNames(includeColumnFiledNames).sheet("标题数据").doWrite(list);
       // EasyExcelUtil.writeExcel(response, list, "标题数据", ViolateTilte.class);

        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), ViolateTilte.class).build() ;

        ArrayList<ViolateTilte> thList = new ArrayList<>();
        ArrayList<ViolateTilte> bkList = new ArrayList<>();

        for (ViolateTilte tilte : list) {
            tilte.setConnectors(tilte.getUrl()+"$$"+tilte.getTilte());
            if (tilte.getStates().equals("同行数据")){
                thList.add(tilte) ;
            }
            if (tilte.getStates().equals("爆款数据")){
                bkList.add(tilte) ;
            }
        }

        WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "同行数据").build() ;
        excelWriter.write(thList, writeSheet1);

        WriteSheet writeSheet2 = EasyExcel.writerSheet(2, "爆款数据").build() ;
        excelWriter.write(bkList, writeSheet2);

        excelWriter.finish();
        response.flushBuffer();


    }

    /**
     * 导出数据Txt
     * @param response
     * @param violateTilte
     */
    public void exportTxt(HttpServletResponse response, ViolateTilte violateTilte) throws Exception {
        List<ViolateTilte> list = this.exportViolateTilteList(violateTilte);


        ArrayList<ViolateTilte> thList = new ArrayList<>();
        ArrayList<ViolateTilte> bkList = new ArrayList<>();

        for (ViolateTilte tilte : list) {
            tilte.setConnectors(tilte.getUrl()+"$$"+tilte.getTilte());
            if (tilte.getStates().equals("同行数据")){
                thList.add(tilte) ;
            }
            if (tilte.getStates().equals("爆款数据")){
                bkList.add(tilte) ;
            }
        }

        //拼接字符串
        StringBuffer textTH = new StringBuffer();
        for(ViolateTilte violateTilte1:thList){
            textTH.append(violateTilte1.getConnectors()) ;
            textTH.append("\r\n");//换行字符
        }
        StringBuffer textBK = new StringBuffer();
        for(ViolateTilte violateTilte1:bkList){
            textBK.append(violateTilte1.getConnectors()) ;
            textBK.append("\r\n");//换行字符
        }
        exportTxt(response,textBK.toString());
        log.info("执行1！！！");
        exportTxt(response,textTH.toString());
        log.info("执行！！！");

    }

    /**
     * 导出数据Zip
     * @param response
     * @param violateTilte
     */
    public void exportZip(HttpServletResponse response, ViolateTilte violateTilte) throws Exception {
        List<ViolateTilte> list = this.exportViolateTilteList(violateTilte);
        List<File> files = new ArrayList<>();
        List<File> filesTh = new ArrayList<>();
        List<File> filesBk = new ArrayList<>();
        String zipFileName = violateTilte.getShop()+"上货数据包" ;
        String zipFileNameTh = violateTilte.getShop()+"同行" ;
        String zipFileNameBk = violateTilte.getShop()+"爆款" ;
        ArrayList<ViolateTilte> thList = new ArrayList<>();
        ArrayList<ViolateTilte> bkList = new ArrayList<>();

        for (ViolateTilte tilte : list) {
            tilte.setConnectors(tilte.getUrl()+"$$"+tilte.getTilte());
            if (tilte.getStates().equals("同行数据")){
                thList.add(tilte) ;
            }
            if (tilte.getStates().equals("爆款数据")){
                bkList.add(tilte) ;
            }
        }
        try{

            //同行
            File outFile1 = new File("C:/temp/txt/"+violateTilte.getShop()+"同行.txt");
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile1,true), "utf-8"), 2);
            for (ViolateTilte th : thList) {
                out.write(th.getConnectors()+"\r\n");
            }
             out.flush();
             files.add(outFile1) ;
             out.close();
            //爆款
            File outFile2 = new File("C:/temp/txt/"+violateTilte.getShop()+"爆款.txt");
            Writer out2 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile2,true), "utf-8"), 2);
            for (ViolateTilte bk : bkList) {
                out2.write(bk.getConnectors()+"\r\n");
            }
            out2.flush();
            files.add(outFile2) ;
            out2.close();


//            //同行每个分成5份
//            int c = thList.size() / 5 ;
//            for (int i1 = 0; i1 < 5; i1++) {
//                File outFile1 = new File("C:/temp/txt/"+violateTilte.getShop()+"同行_"+(i1+1)+".txt");
//                Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile1,true), "utf-8"), 2);
//                for (int i = i1*c; i < (i1==4?thList.size(): (i1+1)*c); i++) {
//                    out.write(thList.get(i).getConnectors() + "\r\n");
//                }
//                out.flush();
//                files.add(outFile1) ;
//                out.close();
//            }
//            //爆款每个分成5份
//            int b = bkList.size() / 5 ;
//            for (int i1 = 0; i1 < 5; i1++) {
//                File outFile1 = new File("C:/temp/txt/"+violateTilte.getShop()+"爆款_"+(i1+1)+".txt");
//                Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile1,true), "utf-8"), 2);
//                for (int i = i1*b; i < (i1==4?bkList.size():(i1+1)*b); i++) {
//                    out.write(bkList.get(i).getConnectors() + "\r\n");
//                }
//                out.flush();
//                files.add(outFile1) ;
//                out.close();
//            }
//            File thFile = new File("C:/temp/txt/"+violateTilte.getShop()+"同行");
//            File bkTile = new File("C:/temp/txt/"+violateTilte.getShop()+"爆款");
//            files.add(thFile) ;
//            files.add(bkTile) ;

            zip(files,zipFileName);
//            FileOutputStream fos2 = new FileOutputStream(new File("E:/temp/"+zipFileName+".zip"));
//            ZipUtils.toZip(files, fos2);

            downloadZip(response , zipFileName) ;

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void zip(List<File> fileList,String zipFileName) {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        ZipOutputStream zipOutputStream = null;
        BufferedInputStream bufferInputStream = null;
        try {
            // zipFileName为压缩文件的名称（xx.zip），首先在某个目录下（C:/temp/路径可以根据自己的需求进行修改）创建一个.zip结尾的文件
            fileOutputStream = new FileOutputStream(new File("C:/temp/" + zipFileName));
            zipOutputStream = new ZipOutputStream(new BufferedOutputStream(fileOutputStream));
            // 创建读写缓冲区
            byte[] bufs = new byte[1024 * 10];

//            //加文件夹 店铺名爆款文件夹和店铺名同行数据文件夹
//            File fileNameTh = new File("C:/temp/txt/"+zipFileName+"同行");
//            File fileNameBk = new File("C:/temp/txt/"+zipFileName+"爆款");
//            ZipEntry zipEntryTh = new ZipEntry(fileNameTh.getName());
//            zipOutputStream.putNextEntry(zipEntryTh);
//
//
//            ZipEntry zipEntryBk = new ZipEntry(fileNameBk.getName());
//            zipOutputStream.putNextEntry(zipEntryBk);
//
//

            for (File file : fileList) {
                // 创建ZIP实体，并添加进压缩包
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zipOutputStream.putNextEntry(zipEntry);
                    // 读取待压缩的文件并写进压缩包里
                    fileInputStream = new FileInputStream(file);
                    bufferInputStream = new BufferedInputStream(fileInputStream, 1024 * 10);
                    int read = 0;
                    while ((read = bufferInputStream.read(bufs, 0, 1024 * 10)) != -1) {
                        zipOutputStream.write(bufs, 0, read);
                    }
                 ;
//                log.info("file.getName()=="+file.getPath());
//                Path path = Paths.get(file.getPath());
//                boolean result = Files.deleteIfExists(path);
////                boolean delete = file.delete();
//                log.info("原文件内容删除完毕"+result);

                FileWriter fileWriter = new FileWriter(file);
                fileWriter.write("");// 清空
                fileWriter.flush();
                fileWriter.close();
                log.info("原文件内容清除完毕");
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferInputStream != null) {
                    bufferInputStream.close();
                }
                if (zipOutputStream != null) {
                    zipOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }



    /* 导出txt文件
     * @author
     * @param	response
     * @param	text 导出的字符串
     * @return
     */
    public void exportTxt(HttpServletResponse response,String text){
        response.setCharacterEncoding("utf-8");
        //设置响应的内容类型
        response.setContentType("text/plain");
        //设置文件的名称和格式
        response.addHeader("Content-Disposition","attachment;filename="
                + genAttachmentFileName( "文件名称", "JSON_FOR_UCC_")//设置名称格式，没有这个中文名称无法显示
                + ".txt");
        BufferedOutputStream buff = null;
        ServletOutputStream outStr = null;
        try {
            outStr = response.getOutputStream();
            buff = new BufferedOutputStream(outStr);
            buff.write(text.getBytes("UTF-8"));
            buff.flush();
            buff.close();
        } catch (Exception e) {
            //LOGGER.error("导出文件文件出错:{}",e);
        } finally {try {
            buff.close();
            outStr.close();
        } catch (Exception e) {
            //LOGGER.error("关闭流对象出错 e:{}",e);
            }
        }
    }


//防止中文文件名显示出错

    public  String genAttachmentFileName(String cnName, String defaultName) {
        try {
            cnName = new String(cnName.getBytes("gb2312"), "ISO8859-1");
        } catch (Exception e) {
            cnName = defaultName;
        }
        return cnName;
    }

    public void downloadZip(HttpServletResponse response, String zipFileName) {
        // zipName为上一步文件打包zip时传入的zipName
        File zipFile = new File("C:/temp/" + zipFileName);
        response.setContentType("APPLICATION/OCTET-STREAM");
        response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);

        FileInputStream fileInputStream = null;
        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            fileInputStream = new FileInputStream(zipFile);
            byte[] bufs = new byte[1024 * 10];
            int read = 0;
            while ((read = fileInputStream.read(bufs, 0, 1024 * 10)) != -1) {
                outputStream.write(bufs, 0, read);
            }
            fileInputStream.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                // 删除压缩包
                File file = new File("C:/temp/" + zipFileName);
                file.delete();

                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 条件导出数据
     *
     * @param violateTilte 标题
     * @return 标题
     */
    public List<ViolateTilte> exportViolateTilteList(ViolateTilte violateTilte){
        //查询数据库所有数据（数据量：50万以上）
        List<ViolateTilte> violateTiltes = violateTilteMapper.exportViolateTitleList(violateTilte);
        if(violateTilte.getShop() == null || violateTilte.getChoose() == null ){
            return violateTiltes ;
        }

        //查询店铺数据信息(几百行)
        ViolateTypeShop violateTypeShop = new ViolateTypeShop() ;
        violateTypeShop.setShopName(violateTilte.getShop()) ;
        List<ViolateTypeShop> violateTypeShops = violateTypeShopService.selectViolateTypeShopList(violateTypeShop);


        //choose 全开选择
        List<ViolateTilte> list = SelectQk(violateTilte.getChoose() , violateTiltes ,violateTypeShops) ;

        //同行价格区间（并且进行链接去重）
        //爆款价格区间（链接+标题一起去重）
        //同行数据的一级类目,爆款数据的一级类目 数量筛选，乱序筛选
        list = priceRange( violateTilte.getPrice_range_th() , violateTilte.getPrice_range_bk(),violateTilte.getThNumber() , violateTilte.getBkNumber() , list) ;


        return list ;
    }


    /**
     * 同行，爆款，价格区间 --并且需要进行去重,同行链接去重，爆款链接，标题
     * 同行爆款乱序数量筛选
     * @param getPrice_range_tH 同行区间
     * @param getPrice_range_bk 爆款区间
     * @param ThNumber
     * @param BkNumber
     * @param list 筛选的数据
     * @return
     */
    private ArrayList<ViolateTilte> priceRange(String getPrice_range_tH ,String getPrice_range_bk ,int ThNumber ,int BkNumber, List<ViolateTilte> list ){
        //同行url去重
        Set<ViolateTilte> titleTH = new TreeSet<>(Comparator.comparing(ViolateTilte::getUrl));
        //爆款url,标题去重
        Set<ViolateTilte> titleBK = new TreeSet<>(Comparator.comparing(o -> (o.getUrl() + "" + o.getTilte())));

        ArrayList<ViolateTilte> newList = new ArrayList<>();

        if (getPrice_range_tH != null && getPrice_range_bk != null){
            String[] str1 = getPrice_range_tH.split("-");
            String[] str2 = getPrice_range_bk.split("-");
            int[] tH = Arrays.stream(str1).mapToInt(Integer::parseInt).toArray();
            int[] bk = Arrays.stream(str2).mapToInt(Integer::parseInt).toArray();

            for (ViolateTilte violateTitle : list) {
                if (violateTitle.getStates() == null ){
                    continue;
                }
                if (violateTitle.getStates().equals("同行数据") && Double.parseDouble(violateTitle.getMoney())>tH[0]  && Double.parseDouble(violateTitle.getMoney())<tH[1]){
                    //同行数据，区间内的数据
                    titleTH.add(violateTitle) ;
                }
                if (violateTitle.getStates().equals("爆款数据") && Double.parseDouble(violateTitle.getMoney())>bk[0]  && Double.parseDouble(violateTitle.getMoney())<bk[1]){
                    //爆款数据，区间内的数据
                    titleBK.add(violateTitle) ;
                }
            }
        }else{
            for (ViolateTilte violateTitle : list) {
                if (violateTitle.getStates() == null ){
                    continue;
                }
                if (violateTitle.getStates().equals("同行数据")){
                    //同行数据，区间内的数据
                    titleTH.add(violateTitle) ;
                }
                if (violateTitle.getStates().equals("爆款数据")){
                    //爆款数据，区间内的数据
                    titleBK.add(violateTitle) ;
                }
            }
        }
        //同行一级类目筛选乱序数量筛选
        newList =  NumberSelect(titleTH , newList , ThNumber) ;
        //爆款一级类目筛选乱序数量筛选
        newList =  NumberSelect(titleBK , newList , BkNumber) ;
        return newList ;
    }

    /**
     * 根据一级类目数量筛选方法
     * @param title
     * @param list
     * @param Number
     * @return
     */
    private ArrayList<ViolateTilte> NumberSelect(Set<ViolateTilte> title , ArrayList<ViolateTilte> list ,int  Number){
        HashMap<String, Integer> map = new HashMap<>();
        ArrayList<ViolateTilte> newList = new ArrayList<>(title);
        Collections.shuffle(newList) ;
        for (ViolateTilte violateTilte : newList) {
            //如果map中有，则计数
            if (map.containsKey(violateTilte.getType1())){
                int count = map.get(violateTilte.getType1()) + 1;
                map.put(violateTilte.getType1() , count) ;
            }else{
                map.put(violateTilte.getType1() , 1) ;
            }
            //判断violateTilte的一级类目是否超过BkNumber,没有超过则添加
            if (Number == 0 || map.get(violateTilte.getType1()) <= Number){
                list.add(violateTilte) ;
            }
        }
        return  list ;
    }


    /**
     * 全开选择方法
     * @param Choose 全开类型
     * @param violateTiltes 总表数据
     * @param violateTypeShops 店铺类目数据
     * @return
     */
    private ArrayList<ViolateTilte> SelectQk(String Choose ,List<ViolateTilte> violateTiltes , List<ViolateTypeShop> violateTypeShops){
        ArrayList<ViolateTilte> list = new ArrayList<>();

        //一级类目全选
        if(Choose.equals("一级类目")){
            Set<String> type1s = new HashSet<>() ;
            for (ViolateTypeShop typeShop : violateTypeShops) {
                type1s.add(typeShop.getTypeCas1()) ;
            }
            for (ViolateTilte violateTitle : violateTiltes) {
                //判断数据库表的数据，是否包含type1s里的数据
                if (type1s.contains(violateTitle.getType1())){
                    list.add(violateTitle) ;
                }
            }
        }

        //判断是否全开
        //一级全开
        if(Choose.equals("一级全开")){
            //获取shop商铺，一级类目所有信息
            List<String> type1s = new ArrayList<>() ;
            for (ViolateTypeShop typeShop : violateTypeShops) {
                type1s.add(typeShop.getTypeOpen1()) ;
            }
            //比对总数据库，找出所有包含一级类目的信息
//            Set<ViolateTilte> sets = new TreeSet<>(Comparator.comparing(o -> (o.getUrl() + "" + o.getTilte())));
            for (ViolateTilte violateTitle : violateTiltes) {
                //判断数据库表的数据，是否包含type1s里的数据
                if (type1s.contains(violateTitle.getType1())){
                    list.add(violateTitle) ;
                }
            }
        }

        //二级全开（对多级类目里进行关键字查询）
        if(Choose.equals("二级全开")){
            //获取shop商铺，二级类目所有信息
            List<String> type2s = new ArrayList<>() ;
            for (ViolateTypeShop typeShop : violateTypeShops) {
                type2s.add(typeShop.getTypeCas2()) ;
            }
            //比对总数据库，找出所有包含二级类目的信息
//            Set<ViolateTilte> sets = new TreeSet<>(Comparator.comparing(o -> (o.getUrl() + "" + o.getTilte())));

            for (ViolateTilte violateTitle : violateTiltes) {
                //判断数据库表的数据，是否包含type1s里的数据
                if (type2s.contains(violateTitle.getType1()) || type2s.contains(violateTitle.getType2()) || type2s.contains(violateTitle.getType3())|| type2s.contains(violateTitle.getType4())|| type2s.contains(violateTitle.getType4())){
                    list.add(violateTitle) ;
                }
            }
        }

        //一级全开和二级全开合并
        if(Choose.equals("一级全开和二级全开合并")){
            String strOne = "一级全开" ;
            String strTwo = "二级全开" ;
            //将一级全开的list和二级全开的list合并起来
             list = SelectQk(strOne , violateTiltes ,violateTypeShops) ;
             list.addAll(SelectQk(strTwo , violateTiltes ,violateTypeShops)) ;
        }

        return list ;
    }

    /**
     * 选择删除
     * @param violateTilte
     * @return
     */
    @Override
    public int deleteSelectList(ViolateTilte violateTilte){
        if (violateTilte.getTilte()==null
                && violateTilte.getType1()==null
                && violateTilte.getType()==null
                && violateTilte.getStates()==null
                && violateTilte.getId()==null
                && violateTilte.getUrl()==null
                && violateTilte.getMoney()==null){
            return 1 ;
        }
        return violateTilteMapper.deleteSelectList(violateTilte) ;
    }


}
